﻿@page "/gpu"

<h1>GPU (WebGL) Canvas</h1>

<p>The canvas below is using WebGL. See the great FPS!</p>

<div class="container">
    <div class="row">
        <div class="col border rounded p-2 canvas-container">

            <SKGLView OnPaintSurface="OnPaintSurface" IgnorePixelScaling="true" EnableRenderLoop="true" />

        </div>
    </div>
</div>

@code {
    int tickIndex = 0;
    long tickSum = 0;
    long[] tickList = new long[100];
    long lastTick = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

    void OnPaintSurface(SKPaintGLSurfaceEventArgs e)
    {
        // the the canvas and properties
        var canvas = e.Surface.Canvas;

        // make sure the canvas is blank
        canvas.Clear(SKColors.White);

        using var paint = new SKPaint
        {
            IsAntialias = true,
            StrokeWidth = 5f,
            StrokeCap = SKStrokeCap.Round,
            TextAlign = SKTextAlign.Center,
            TextSize = 24,
        };

        var surfaceSize = e.Info.Size;
        var clockSize = Math.Min(surfaceSize.Width, surfaceSize.Height) * 0.4f;
        var center = new SKPoint(surfaceSize.Width / 2f, surfaceSize.Height / 2f);
        var now = DateTime.Now;
        var fps = GetCurrentFPS();

        // draw the fps counter
        canvas.DrawText($"{fps:0.00}fps", surfaceSize.Width / 2, surfaceSize.Height - 10f, paint);

        // draw the clock
        canvas.RotateDegrees(-90f, center.X, center.Y);

        // hours
        paint.StrokeWidth = 3f;
        canvas.Save();
        canvas.Translate(center);
        canvas.RotateDegrees(360f * (now.Hour / 12f));
        canvas.DrawLine(0, 0, clockSize * 0.4f, 0, paint);
        canvas.Restore();

        // minutes
        paint.StrokeWidth = 2f;
        canvas.Save();
        canvas.Translate(center);
        canvas.RotateDegrees(360f * (now.Minute / 60f));
        canvas.DrawLine(0, 0, clockSize * 0.6f, 0, paint);
        canvas.Restore();

        // seconds
        paint.StrokeWidth = 1f;
        canvas.Save();
        canvas.Translate(center);
        canvas.RotateDegrees(360f * ((now.Second * 1000f + now.Millisecond) / 1000f / 60f));
        canvas.DrawLine(0, 0, clockSize * 0.8f, 0, paint);
        canvas.Restore();

        // center
        canvas.DrawCircle(center, 10f, paint);

        // border
        paint.Style = SKPaintStyle.Stroke;
        canvas.DrawCircle(center, clockSize * 0.9f, paint);
    }

    double GetCurrentFPS()
    {
        var newTick = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
        var delta = newTick - lastTick;
        lastTick = newTick;

        tickSum -= tickList[tickIndex];
        tickSum += delta;
        tickList[tickIndex] = delta;

        if (++tickIndex == tickList.Length)
            tickIndex = 0;

        return 1000.0 / ((double)tickSum / tickList.Length);
    }
}
